//
//  Bundle+RL.swift
//  RaveLand
//
//  Created by CS001 on 2021/4/20.
//  Copyright © 2021 CSLY. All rights reserved.
//

import HandyJSON
import Foundation
import BWToolKit

extension Bundle {
    public static func bw_podResourceBundle(_ podName: String) -> Bundle? {
        guard var aURL = Bundle.main.url(forResource: "Frameworks", withExtension: nil) else {
            return nil
        }
        aURL.appendPathComponent(podName)
        aURL = aURL.appendingPathExtension("framework")
        
        guard
            let frameworkBundle = Bundle(url: aURL),
            let aURL = frameworkBundle.url(forResource: podName, withExtension: "bundle"),
            let resourceBundle = Bundle(url: aURL)
        else {
            return nil
        }
        
        return resourceBundle
    }
}


extension Bundle {
    public enum JSONError: Error {
        case serializedError
        case catchedError(Error)
    }
    
    public func bw_loadJSONFile(
        name: String,
        completion: BlockTT<JSONError?, Any?>?
    ) {
        let resource = name.contains(".json") ? name : "\(name).json"
        do {
            guard let aURL = url(forResource: resource, withExtension: nil) else {
                return
            }
            let data = try Data(contentsOf: aURL)
            guard let object = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) else {
                DispatchQueue.main.async {
                    completion?(.serializedError, nil)
                }
                return
            }
            DispatchQueue.main.async {
                completion?(nil, object)
            }
        } catch {
            DispatchQueue.main.async {
                completion?(.catchedError(error), nil)
            }
        }
    }
    
    public func bw_loadJSONArray<T: HandyJSON>(
        name: String,
        completion: BlockTT<JSONError?, [T]?>?
    ) {
        bw_loadJSONFile(name: name) {
            guard let array = $1 as? JSONArray else {
                completion?($0, nil)
                return
            }
            let list = array.compactMap{ T.deserialize(from: $0) }
            completion?($0, list)
        }
    }
    
    public func bw_loadJSONDictionary<T: HandyJSON>(
        name: String,
        completion: BlockTT<JSONError?, T?>?
    ) {
        bw_loadJSONFile(name: name) {
            guard let dict = $1 as? JSONDictionary else {
                completion?(.serializedError, nil)
                return
            }
            completion?($0, T.deserialize(from: dict))
        }
    }
}
